if InstalledFzf()
    source $CFG_PATH/fzf.vim
endif
if Installed('leaderf')
    source $CFG_PATH/leaderf.vim
    if Installed('leaderf-filer')
        source $CFG_PATH/leaderf-filer.vim
    endif
endif
if InstalledFzf() && (get(g:, 'prefer_fzf', UNIX()) || !Installed('leaderf'))
    nnoremap <silent><M-k><M-k> :FzfCommands<Cr>
    nnoremap <silent><M-k>c :FzfColors<Cr>
    nnoremap <silent><M-k>t :FzfFiletypes<Cr>
elseif Installed('leaderf')
    nnoremap <silent><M-k><M-k> :LeaderfCommand<Cr>
    nnoremap <silent><M-k>c :LeaderfColorscheme<Cr>
    nnoremap <silent><M-k>t :LeaderfFiletype<Cr>
else
    let g:fuzzy_finder = ''
    nnoremap <M-k><M-k> :command
    nnoremap <M-k>c :colorscheme
    nnoremap <M-k>t :setfiletype
endif
if Installed('leaderf')
    nnoremap <silent><M-h><M-h> :LeaderfHelp<Cr>
elseif InstalledFzf() && executable('perl')
    nnoremap <silent><M-h><M-h> :FzfHelptags<Cr>
else
    nnoremap <M-h><M-h> :h<Space>
endif
" <c-h>/<c-p> map
if InstalledCoc()
    command! CocFzfListCommands CocFzfList commands
    nnoremap <silent><leader>C :CocFzfListCommands<Cr>
    command! FzfLeaderfCommands call FzfCallCommands('FzfLeaderfCommands', 'CocFzfList', 'Fzf', 'Leaderf', ['FzfAg', 'FzfRG'])
    nnoremap <silent><C-p> :FzfLeaderfCommands<Cr>
else
    if InstalledFzf()
        if Installed('leaderf')
            command! LeaderfFzfCommands call FzfCallCommands('LeaderfFzfCommands', 'Leaderf', 'Fzf', ['FzfAg', 'FzfRG'])
            nnoremap <silent><C-p> :LeaderfFzfCommands<Cr>
        else
            command! FzfCommands call FzfCallCommands('FzfCommands', 'Fzf', ['FzfAg', 'FzfRG'])
            nnoremap <silent><C-p> :FzfCommands<Cr>
        endif
    elseif Installed('leaderf')
        nnoremap <silent><C-p> :LeaderfSelf<Cr>
    endif
endif
" ------------------------------
" vim-preview
" ------------------------------
let g:preview#preview_position = "rightbottom"
let g:preview#preview_size = get(g:, 'asyncrun_open', 8)
nnoremap <M-M> <C-w>z
PlugAddOpt 'vim-preview'
" --------------------------
" vim-quickui
" --------------------------
if v:version >= 802 || has('nvim')
    let g:quickui_border_style = 2
    if has('nvim')
        if HAS_GUI()
            let g:quickui_color_scheme = 'gruvbox'
        else
            let g:quickui_color_scheme = 'papercol dark'
        endif
    else
        if HAS_GUI()
            let g:quickui_color_scheme = 'borland'
        else
            let g:quickui_color_scheme = 'papercol light'
        endif
    endif
    PlugAddOpt 'vim-quickui'
    nnoremap <silent><M-k>m :call quickui#tools#display_messages()<Cr>
    function! s:preview_popup_file(filename) abort
        let filename = a:filename
        let fopts = {'cursor':-1, 'number':1, 'persist':0, 'w':80, 'h':64}
        call quickui#preview#open(filename, fopts)
    endfunction
    command! -nargs=1 -complete=file PreviewPopupFile call s:preview_popup_file(<f-args>)
    nnoremap <Tab>o :PreviewPopupFile
    nnoremap <F13> :call quickui#preview#scroll(1)<Cr>
    nnoremap <F14> :call quickui#preview#scroll(-1)<Cr>
    if InstalledCoc()
        nmap <silent><expr><C-j> coc#float#has_scroll() ? coc#float#scroll(1) : quickui#preview#visible() > 0 ? "\<F13>" : "\%"
        nmap <silent><expr><C-k> coc#float#has_scroll() ? coc#float#scroll(0) : quickui#preview#visible() > 0 ? "\<F14>" : "\g%"
    else
        nmap <silent><expr><C-j> quickui#preview#visible() > 0 ? "\<F13>" : "\%"
        nmap <silent><expr><C-k> quickui#preview#visible() > 0 ? "\<F14>" : "\g%"
    endif
else
    nnoremap <Tab>o :PreviewFile
    nnoremap <silent><M-k>m :messages<Cr>
    nmap <C-j> %
    xmap <C-j> %
    nmap <C-k> g%
    xmap <C-k> g%
endif
" Choose one from a list
function! s:get_char_form_lst(lst, cmd) abort
    let lst = a:lst
    let cmd = a:cmd
    let ext = '123456789!@#$%^*-=_+'
    let l_c = len(cmd)
    let l_e = len(ext)
    for i in range(l_c)
        if index(lst, cmd[i]) < 0
            call add(lst, cmd[i])
            if i == 0
                return [lst, '&' . cmd]
            else
                return [lst,  cmd[:i-1] . '&' . cmd[i+1:]]
            endif
        endif
    endfor
    for i in range(l_e)
        if index(lst, ext[i]) < 0
            call add(lst, ext[i])
            return [lst, '&' . ext[i] . cmd]
        endif
    endfor
    return [lst, cmd]
endfunction
function! ChooseOne(lst, ...) abort
    let cmds = a:lst
    if len(cmds) == 0
        return ""
    endif
    if a:0
        let title = a:1
    else
        let title = "Please choose one."
    endif
    if a:0 >= 2 && a:2 >= 1
        let add_num = 1
    else
        let add_num = 0
    endif
    if len(cmds) > 9
        let cmds=cmds[:8]
    endif
    let cnt = 0
    let lines = []
    for cmd in cmds
        let cnt += 1
        if add_num
            call add(lines, '&' . cnt . ' '. cmd)
        else
            if !exists('char_lst')
                let char_lst = []
            endif
            let [char_lst, cmd] = s:get_char_form_lst(char_lst, cmd)
            call add(lines, cmd)
        endif
    endfor
    if Installed('vim-quickui')
        let opts = {'title': title, 'index':g:quickui#listbox#cursor, 'w': 64}
        let idx = quickui#listbox#inputlist(lines, opts)
        if idx >= 0
            return cmds[idx]
        endif
    else
        let cnt += 1
        if a:0 >= 3 && a:3 != ''
            call add(lines, '&' . a:3)
        else
            call add(lines, '&0None')
        endif
        let content = join(lines, "\n")
        let idx = confirm(title, content, cnt)
        if idx > 0 && idx < cnt
            return cmds[idx-1]
        endif
    endif
    return ""
endfunction
" --------------------
" ZFIgnore
" --------------------
autocmd User ZFIgnoreOnUpdate let &wildignore = join(ZFIgnoreToWildignore(ZFIgnoreGet()), ',')
function! s:ZFIgnore_LeaderF()
    let ignore = ZFIgnoreGet()
    let g:Lf_WildIgnore = {'file' : ignore['file'], 'dir' : ignore['dir']}
endfunction
autocmd User ZFIgnoreOnUpdate call s:ZFIgnore_LeaderF()
let g:ZFIgnoreOption_ZFDirDiff = {
            \   'bin' : 0,
            \   'media' : 0,
            \   'ZFDirDiff' : 1,
            \ }
PlugAddOpt 'ZFVimJob'
PlugAddOpt 'ZFVimIgnore'
" --------------------
" ZFVimDirDiff
" --------------------
let g:ZFDirDiff_ignoreEmptyDir = 1
let g:ZFDirDiffKeymap_update = ['DD', '<Tab>']
let g:ZFDirDiffKeymap_updateParent = ['DU']
let g:ZFDirDiffKeymap_open = ['<cr>', 'o']
let g:ZFDirDiffKeymap_foldOpenAll = ['DO']
let g:ZFDirDiffKeymap_foldOpenAllDiff = ['O']
let g:ZFDirDiffKeymap_foldClose = ['x']
let g:ZFDirDiffKeymap_foldCloseAll = ['X']
let g:ZFDirDiffKeymap_diffThisDir = ['DL', 'cd']
let g:ZFDirDiffKeymap_diffParentDir = ['u']
let g:ZFDirDiffKeymap_goParent = ['U']
let g:ZFDirDiffKeymap_markToDiff = ['DM']
let g:ZFDirDiffKeymap_markToSync = ['DS']
let g:ZFDirDiffKeymap_quit = ['q', '<leader>q', 'Q']
let g:ZFDirDiffKeymap_diffNext = [']c', 'DN']
let g:ZFDirDiffKeymap_diffPrev = ['[c', 'DP']
let g:ZFDirDiffKeymap_diffNextFile = ['DJ']
let g:ZFDirDiffKeymap_diffPrevFile = ['DK']
let g:ZFDirDiffKeymap_syncToHere = ['DH']
let g:ZFDirDiffKeymap_syncToThere = ['DT']
let g:ZFDirDiffKeymap_add = ['a', '+']
let g:ZFDirDiffKeymap_delete = ['dd']
let g:ZFDirDiffKeymap_getPath = ['y', 'p']
let g:ZFDirDiffKeymap_getFullPath = ['Y', 'P']
PlugAddOpt 'ZFVimDirDiff'
" --------------------
" ZFVimBackup
" --------------------
let g:ZFBackup_autoEnable = 0
nnoremap <M-j><M-s> :ZFBackupSave<Cr>
nnoremap <M-j><M-l> :ZFBackupList<Cr>
nnoremap <M-j><M-d> :ZFBackupListDir<Cr>
nnoremap <M-j><M-m> :ZFBackupRemove<Cr>
nnoremap <M-j><M-r> :ZFBackupRemoveDir<Cr>
function! s:zfbackup_cleanup() abort
    let confirm = ChooseOne(['yes', 'no'], "Cleanup all ZFBackup files")
    if confirm == 'yes'
        if WINDOWS()
            exec printf('!del %s\*.* /a /f /q', ZFBackup_backupDir())
        else
            exec printf('!rm -rf %s/*.*', ZFBackup_backupDir())
        endif
    endif
endfunction
nnoremap <silent><M-j><M-c> :call <SID>zfbackup_cleanup()<Cr>
function! s:zfbackup_savedir() abort
    let confirm = ChooseOne(['yes', 'no'], "Save current dir using ZFBackup?")
    if confirm == 'yes'
        call preview#cmdmsg("Start to save files under current dir", 1)
        ZFBackupSaveDir
    endif
endfunction
nnoremap <silent><M-j><M-b> :call <SID>zfbackup_savedir()<Cr>
PlugAddOpt 'ZFVimBackup'
